package cn.snmp.mutual.adapter;
import java.math.BigInteger;

import cn.snmp.mutual.constants.SnmpParametrConstante;
import cn.snmp.mutual.nms.SnmpAPI;
import cn.snmp.mutual.nms.SnmpCounter64;
import cn.snmp.mutual.nms.SnmpString;
import cn.snmp.mutual.nms.SnmpVar;
import lombok.extern.slf4j.Slf4j;
import cn.snmp.mutual.data.ObjService;
import cn.snmp.mutual.util.DumpUtil;
/**
 * @author dengkn
 * MIB NODE Adapter ，extends GeneralMibNodeAdapter
 * 在读取和写入snmp mib node 的时候实现readMibData、writeMibData方法
 * GeneralMibNodeAdapter 默认实现类
 */
@Slf4j
public class GeneralMibNodeAdapter extends AbstractMibNodeAdapter {

	public static final String SPLIT_CHARACTER = ":";
	public static final int BIT_MAX_UNMBER = 8;
	
	/**
	 * Mib Node Adapter or Conversion type
	 * @param var data value var
	 * @param mibnode mib node Objservice 
	 * @return value String
	 * */
	@Override
	public String readMibData(SnmpVar var, ObjService mibnode) {
		String syntaxName = mibnode.getStringValue(SnmpParametrConstante.SYNRAX_NAME);
		if ("".equals(syntaxName)) {
			syntaxName = mibnode.getStringValue(SnmpParametrConstante.DATA_TYPE);
		}
		String typeString = mibnode.getStringValue(SnmpParametrConstante.TYPR_STRING);
		if (SnmpParametrConstante.MAC_ADDRESS.equalsIgnoreCase(syntaxName)) {
			return returnMac(var);
		} else if (SnmpParametrConstante.PHYSADDRESS.equalsIgnoreCase(syntaxName)) {
			return returnPhysAddress(var);
		} else if (SnmpParametrConstante.BITS.equalsIgnoreCase(syntaxName)) {
			return returnBits(var);
		} else if (SnmpParametrConstante.COUNTER64.equalsIgnoreCase(syntaxName)) {
			return returnCounter64(var);
		} else if (SnmpParametrConstante.BRIDGE_ID.equalsIgnoreCase(syntaxName)) {
			return returnBridgeId(var);
		}else if (SnmpParametrConstante.IP_ADDRESS.equalsIgnoreCase(syntaxName)) {
			return var.toString();
		} else if (SnmpParametrConstante.IPADDRESS.equalsIgnoreCase(syntaxName)) {
			return var.toString();
		} else if (SnmpParametrConstante.SNMP_TYPE_STRING.equalsIgnoreCase(typeString)) {
			byte strByteList[] = var.toBytes();
			return new String(strByteList);
		}
		return var.toString();
	}

	private String returnMac(SnmpVar var) {
		if (var instanceof SnmpString) {
			String macaddr = ((SnmpString) var).toString();
			if (!macaddr.contains(SPLIT_CHARACTER)) {
				macaddr = ((SnmpString) var).toByteString();
			}
			macaddr = macaddr.trim();
			macaddr = macaddr.replace(' ', ':');
			return macaddr;
		} else {
			return "";
		}
	}

	private String returnPhysAddress(SnmpVar var) {
		if (var instanceof SnmpString) {
			String macaddr = ((SnmpString) var).toString();
			if (!macaddr.contains(SPLIT_CHARACTER)) {
				macaddr = ((SnmpString) var).toByteString();
			}
			macaddr = macaddr.trim();
			macaddr = macaddr.replace(' ', ':');
			return macaddr;
		} else {
			return "";
		}

	}

	private String returnBits(SnmpVar var) {
		if (var instanceof SnmpString) {
			StringBuilder b = new StringBuilder();
			byte bits[] = ((SnmpString) var).toBytes();
			int value = 0;
			for (int i = 0; i < bits.length; i++) {
				value = i * 8;
				byte pos = (byte) 0x80;
				for (int j = 0; j < BIT_MAX_UNMBER; j++) {
					if ((pos & bits[i]) != 0) {
						b.append(value);
						b.append(',');
					}
					pos = (byte) (pos / 2);
					value++;
				}
			}
			if (b.length() > 0) {
				b.deleteCharAt(b.length() - 1);
			}
			return b.toString();
		} else {
			return "";
		}

	}

	private String returnCounter64(SnmpVar var) {
		if (var instanceof SnmpCounter64) {
			BigInteger counter = ((SnmpCounter64) var).toBigInteger();
			return counter.toString();
		} else {
			return "";
		}

	}

	private String returnBridgeId(SnmpVar var) {
		if (var instanceof SnmpString) {
			return ((SnmpString) var).toByteString();
		} else {
			return "";
		}
	}
	
	@Override
	public SnmpVar writeMibData(String value, ObjService mibnode) {
		SnmpVar var = null;
		String syntaxName = mibnode.getStringValue(SnmpParametrConstante.SYNRAX_NAME);
		String label = mibnode.getStringValue("Label");
		String syntax = mibnode.getStringValue("Syntax");
		String typeString = mibnode.getStringValue("DataType");
		log.debug("[" + label + "],[" + syntaxName + "],[" + syntax + "], Value is [" + value + "]");
		try {
			if (SnmpParametrConstante.INTEGER.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.INTEGER);
			} else if (SnmpParametrConstante.SNMP_TYPE_STRING.equalsIgnoreCase(typeString)) {
				byte[] strByteList = value.getBytes();
				var = new SnmpString(strByteList);
			} else if (SnmpParametrConstante.OBJID.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.OBJID);
			} else if (SnmpParametrConstante.NULLOBJ.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.NULLOBJ);
			} else if (SnmpParametrConstante.IPADDRESS.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.IPADDRESS);
			} else if (SnmpParametrConstante.BITSTRING.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.BITSTRING);
			} else if (SnmpParametrConstante.COUNTER.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.COUNTER);
			} else if (SnmpParametrConstante.GAUGE.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.GAUGE);
			} else if (SnmpParametrConstante.UNSIGNED32.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.UNSIGNED32);
			} else if (SnmpParametrConstante.TIMETICKS.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.TIMETICKS);
			} else if (SnmpParametrConstante.OPAQUE.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.OPAQUE);
			} else if (SnmpParametrConstante.NSAP.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.NSAP);
			} else if (SnmpParametrConstante.COUNTER64.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.COUNTER64);
			} else if (SnmpParametrConstante.UINTEGER32.equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.UINTEGER32);
			} else if (SnmpParametrConstante.OCTETSTRING.equalsIgnoreCase(typeString)) {
				byte[] strByteList = value.getBytes();
				var = new SnmpString(strByteList);
			} else if ("Integer32".equalsIgnoreCase(typeString)) {
				var = SnmpVar.createVariable(value, SnmpAPI.INTEGER);
			}
			if (var == null) {
				DumpUtil.debug("Syntax Name : [" + syntaxName + "] not found...");
			}
			return var;
		} catch (Exception e) {
			log.error("writeMibData error" + e);
			DumpUtil.debug(e);
			return null;
		}
	}
}
